/*Copyright (C) 2010-2012 RAAFCOM B.V. All rights reserved.

This file is part of Velsto and may be used under the terms of:
The GNU General Public License version 3 or higher, as published by
the Free Software Foundation.

This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.*/
/* 
* Application  : Velsto
* Class        : ColorSchemes_velsto
* 01/07/2012   : M.A.van Ravesteijn (Raafcom)
*                v1.2 initial version (methods moved from FormMap)
*  
* Class to contain all ColorScheme affairs for FormMap
* 
*/ 
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Globalization;

namespace Velsto
{

	/// <summary>
	/// Summary description for ColorSchemes_velsto.
	/// </summary>
	public class ColorSchemes_velsto
	{
		
        public ColorSchemes_velsto()
		{
			
		}

        public MapWinGIS.GridColorScheme setColorScheme(int cscb, MapWinGIS.GridColorScheme gcs, bool graphCreated,
                                                         float leftReal, float rightReal, double min, double max)
        {
            Constants constants = new Constants();
            switch (cscb)
            {
                case Constants.COLOR_RAINBOW:
                    gcs = this.RainbowGcs(gcs, graphCreated, leftReal, rightReal, min, max);
                    break;
                case Constants.COLOR_SUMMERMOUNTAINS:
                    gcs = this.StandardGcs(gcs, graphCreated, leftReal, rightReal, min, max,
                    constants.COLOR_SUM_L, constants.COLOR_SUM_M,constants.COLOR_SUM_H);
                    break;
                case Constants.COLOR_DEADSEA:
                    gcs = this.StandardGcs(gcs, graphCreated, leftReal, rightReal, min, max,
                    constants.COLOR_DEA_L, constants.COLOR_DEA_M, constants.COLOR_DEA_H);
                    break;
                case Constants.COLOR_DESERT:
                    gcs = this.StandardGcs(gcs, graphCreated, leftReal, rightReal, min, max,
                    constants.COLOR_DES_L, constants.COLOR_DES_M, constants.COLOR_DES_H);
                    break;
                case Constants.COLOR_FALLLEAVES:
                    gcs = this.StandardGcs(gcs, graphCreated, leftReal, rightReal, min, max,
                    constants.COLOR_FAL_L, constants.COLOR_FAL_M, constants.COLOR_FAL_H);
                    break;
                case Constants.COLOR_GLACIERS:
                    gcs = this.StandardGcs(gcs, graphCreated, leftReal, rightReal, min, max,
                    constants.COLOR_GLA_L, constants.COLOR_GLA_M, constants.COLOR_GLA_H); 
                    break;
                case Constants.COLOR_VALLEYFIRES:
                    gcs = this.StandardGcs(gcs, graphCreated, leftReal, rightReal, min, max,
                    constants.COLOR_VAL_L, constants.COLOR_VAL_M, constants.COLOR_VAL_H);
                    break;
            }
            return gcs;
        }

        public ArrayList setHistColorScheme(int cscb, ArrayList arX, float leftReal, float rightReal,
                                            double min, double max)
        {
            ArrayList arC = new ArrayList();
            Constants constants = new Constants();
            switch (cscb)
            {
                case Constants.COLOR_RAINBOW:
                    arC = this.rainbowHist(arX, leftReal, rightReal, min, max);
                    break;
                case Constants.COLOR_SUMMERMOUNTAINS:
                    arC = this.standardHist(arX, leftReal, rightReal, min, max,
                    constants.COLOR_SUM_L, constants.COLOR_SUM_M, constants.COLOR_SUM_H);
                    break;
                case Constants.COLOR_DEADSEA:
                    arC = this.standardHist(arX, leftReal, rightReal, min, max,
                    constants.COLOR_DEA_L, constants.COLOR_DEA_M, constants.COLOR_DEA_H);
                    break;
                case Constants.COLOR_DESERT:
                    arC = this.standardHist(arX, leftReal, rightReal, min, max,
                    constants.COLOR_DES_L, constants.COLOR_DES_M, constants.COLOR_DES_H);
                    break;
                case Constants.COLOR_FALLLEAVES:
                    arC = this.standardHist(arX, leftReal, rightReal, min, max,
                    constants.COLOR_FAL_L, constants.COLOR_FAL_M, constants.COLOR_FAL_H);
                    break;
                case Constants.COLOR_GLACIERS:
                    arC = this.standardHist(arX, leftReal, rightReal, min, max,
                    constants.COLOR_GLA_L, constants.COLOR_GLA_M, constants.COLOR_GLA_H);
                    break;
                case Constants.COLOR_VALLEYFIRES:
                    arC = this.standardHist(arX, leftReal, rightReal, min, max,
                    constants.COLOR_VAL_L, constants.COLOR_VAL_M, constants.COLOR_VAL_H);
                    break;
            }
            return arC;
        }
        
        private MapWinGIS.GridColorScheme RainbowGcs(MapWinGIS.GridColorScheme gcs, bool graphCreated,
                                                     float leftReal, float rightReal, double min2, double max2)
        {
            double min, max;
            MapWinGIS.GridColorBreak cbleft = new MapWinGIS.GridColorBreak();
            MapWinGIS.GridColorBreak cb1 = new MapWinGIS.GridColorBreak();
            MapWinGIS.GridColorBreak cb2 = new MapWinGIS.GridColorBreak();
            MapWinGIS.GridColorBreak cb3 = new MapWinGIS.GridColorBreak();
            MapWinGIS.GridColorBreak cb4 = new MapWinGIS.GridColorBreak();
            MapWinGIS.GridColorBreak cb5 = new MapWinGIS.GridColorBreak();
            MapWinGIS.GridColorBreak cb6 = new MapWinGIS.GridColorBreak();
            MapWinGIS.GridColorBreak cbright = new MapWinGIS.GridColorBreak();

            if (graphCreated)
            {
                min = leftReal;
                max = rightReal;
                cbleft.LowColor = Convert.ToUInt32(ColorTranslator.ToOle(Color.Red));
                cbleft.HighColor = Convert.ToUInt32(ColorTranslator.ToOle(Color.Red));
                cbleft.LowValue = rnd(min2);
                cbleft.HighValue = rnd(min);
                gcs.InsertBreak(cbleft);
            }
            else
            {
                min = min2;
                max = max2;
            }
            double step = rnd((max - min) / 6.0);
            cb1.LowColor = Convert.ToUInt32(ColorTranslator.ToOle(Color.Red));
            cb1.HighColor = Convert.ToUInt32(ColorTranslator.ToOle(Color.Orange));
            cb1.LowValue = rnd(min);
            cb1.HighValue = rnd(min + (1.0 * step));
            cb2.LowColor = Convert.ToUInt32(ColorTranslator.ToOle(Color.Orange));
            cb2.HighColor = Convert.ToUInt32(ColorTranslator.ToOle(Color.Yellow));
            cb2.LowValue = rnd(min + (1.0 * step));
            cb2.HighValue = rnd(min + (2.0 * step));
            cb3.LowColor = Convert.ToUInt32(ColorTranslator.ToOle(Color.Yellow));
            cb3.HighColor = Convert.ToUInt32(ColorTranslator.ToOle(Color.LightGreen));
            cb3.LowValue = rnd(min + (2.0 * step));
            cb3.HighValue = rnd(min + (3.0 * step));
            cb4.LowColor = Convert.ToUInt32(ColorTranslator.ToOle(Color.LightGreen));
            cb4.HighColor = Convert.ToUInt32(ColorTranslator.ToOle(Color.LightBlue));
            cb4.LowValue = rnd(min + (3.0 * step));
            cb4.HighValue = rnd(min + (4.0 * step));
            cb5.LowColor = Convert.ToUInt32(ColorTranslator.ToOle(Color.LightBlue));
            cb5.HighColor = Convert.ToUInt32(ColorTranslator.ToOle(Color.DodgerBlue));
            cb5.LowValue = rnd(min + (4.0 * step));
            cb5.HighValue = rnd(min + (5.0 * step));
            cb6.LowColor = Convert.ToUInt32(ColorTranslator.ToOle(Color.DodgerBlue));
            cb6.HighColor = Convert.ToUInt32(ColorTranslator.ToOle(Color.DarkBlue));
            cb6.LowValue = rnd(min + (5.0 * step));
            cb6.HighValue = rnd(max);
            gcs.InsertBreak(cb1);
            gcs.InsertBreak(cb2);
            gcs.InsertBreak(cb3);
            gcs.InsertBreak(cb4);
            gcs.InsertBreak(cb5);
            gcs.InsertBreak(cb6);
            ; if (graphCreated)
            {
                cbright.LowColor = Convert.ToUInt32(ColorTranslator.ToOle(Color.DarkBlue));
                cbright.HighColor = Convert.ToUInt32(ColorTranslator.ToOle(Color.DarkBlue));
                cbright.LowValue = rnd(max);
                cbright.HighValue = rnd(max2);
                gcs.InsertBreak(cbright);
            }
            //MessageBox.Show(min2.ToString() + " " + min.ToString() + " " + max.ToString() + " " + max2.ToString());
            return gcs;
        }

        public ArrayList rainbowHist(ArrayList arX, float leftReal, float rightReal, double min2, double max2)
        {
            ArrayList arC = new ArrayList();
            ArrayList cs_low = new ArrayList();
            ArrayList cs_high = new ArrayList();
            ArrayList cs_color_low = new ArrayList();
            ArrayList cs_color_high = new ArrayList();

            double min,max;
            min = leftReal;
            max = rightReal;
            cs_color_low.Add(Color.Red);
            cs_color_high.Add(Color.Red);
            cs_low.Add(rnd(min2));
            cs_high.Add(rnd(min));
            double step = rnd((max - min) / 6.0);
            cs_color_low.Add(Color.Red);
            cs_color_high.Add(Color.Orange);
            cs_low.Add(rnd(min));
            cs_high.Add(rnd(min + (1.0*step)));
            cs_color_low.Add(Color.Orange);
            cs_color_high.Add(Color.Yellow);
            cs_low.Add(rnd(min + (1.0*step)));
            cs_high.Add(rnd(min + (2.0*step)));
            cs_color_low.Add(Color.Yellow);
            cs_color_high.Add(Color.LightGreen);
            cs_low.Add(rnd(min + (2.0*step)));
            cs_high.Add(rnd(min + (3.0*step)));
            cs_color_low.Add(Color.LightGreen);
            cs_color_high.Add(Color.LightBlue);
            cs_low.Add(rnd(min + (3.0*step)));
            cs_high.Add(rnd(min + (4.0*step)));
            cs_color_low.Add(Color.LightBlue);
            cs_color_high.Add(Color.DodgerBlue);
            cs_low.Add(rnd(min + (4.0*step)));
            cs_high.Add(rnd(min + (5.0*step)));
            cs_color_low.Add(Color.DodgerBlue);
            cs_color_high.Add(Color.DarkBlue);
            cs_low.Add(rnd(min + (5.0*step)));
            cs_high.Add(rnd(max));
            cs_color_low.Add(Color.DarkBlue);
            cs_color_high.Add(Color.DarkBlue);
            cs_low.Add(rnd(max));
            cs_high.Add(rnd(max2));
            bool found = false;
            // get interpolated color
            for (int i = 0; i < arX.Count; i++)
            {
                found = false;
                for (int j = 0; j < cs_low.Count ; j++)
                {
                    if (!found && (double) arX[i] >= (double) cs_low[j] && (double) arX[i] < (double) cs_high[j])
                    {
                        arC.Add(graduateColor((double) arX[i],(double) cs_low[j],(double) cs_high[j],
                                                               (Color) cs_color_low[j],(Color) cs_color_high[j]));
                        found = true;
                    }
                }
                if (!found) arC.Add(Color.Black);
            }
            return arC;
        }

        private MapWinGIS.GridColorScheme StandardGcs(MapWinGIS.GridColorScheme gcs, bool graphCreated,
                                                     float leftReal, float rightReal, double min2, double max2,
                                                     Color lowCol, Color midCol, Color higCol)
        {
            double min, max;
            MapWinGIS.GridColorBreak cbleft = new MapWinGIS.GridColorBreak();
            MapWinGIS.GridColorBreak cb1 = new MapWinGIS.GridColorBreak();
            MapWinGIS.GridColorBreak cb2 = new MapWinGIS.GridColorBreak();
            MapWinGIS.GridColorBreak cbright = new MapWinGIS.GridColorBreak();

            if (graphCreated)
            {
                min = leftReal;
                max = rightReal;
                cbleft.LowColor = Convert.ToUInt32(ColorTranslator.ToOle(lowCol));
                cbleft.HighColor = Convert.ToUInt32(ColorTranslator.ToOle(lowCol)); 
                cbleft.LowValue = rnd(min2);
                cbleft.HighValue = rnd(min);
                gcs.InsertBreak(cbleft);
            }
            else
            {
                min = min2;
                max = max2;
            }
            double step = rnd((max - min) / 2.0);
            cb1.LowColor = Convert.ToUInt32(ColorTranslator.ToOle(lowCol));
            cb1.HighColor = Convert.ToUInt32(ColorTranslator.ToOle(midCol));
            cb1.LowValue = rnd(min);
            cb1.HighValue = rnd(min + (1.0 * step));
            cb2.LowColor = Convert.ToUInt32(ColorTranslator.ToOle(midCol));
            cb2.HighColor = Convert.ToUInt32(ColorTranslator.ToOle(higCol));
            cb2.LowValue = rnd(min + (1.0 * step));
            cb2.HighValue = rnd(min + (2.0 * step));
            
            gcs.InsertBreak(cb1);
            gcs.InsertBreak(cb2);
            ; if (graphCreated)
            {
                cbright.LowColor = Convert.ToUInt32(ColorTranslator.ToOle(higCol));
                cbright.HighColor = Convert.ToUInt32(ColorTranslator.ToOle(higCol));
                cbright.LowValue = rnd(max);
                cbright.HighValue = rnd(max2);
                gcs.InsertBreak(cbright);
            }
            //MessageBox.Show(min2.ToString() + " " + min.ToString() + " " + max.ToString() + " " + max2.ToString());
            return gcs;
        }

        public ArrayList standardHist(ArrayList arX, float leftReal, float rightReal, 
                                      double min2, double max2,
                                      Color lowCol, Color midCol, Color higCol)
        {
            ArrayList arC = new ArrayList();
            ArrayList cs_low = new ArrayList();
            ArrayList cs_high = new ArrayList();
            ArrayList cs_color_low = new ArrayList();
            ArrayList cs_color_high = new ArrayList();

            double min, max;
            min = leftReal;
            max = rightReal;
            cs_color_low.Add(lowCol);
            cs_color_high.Add(lowCol);
            cs_low.Add(rnd(min2));
            cs_high.Add(rnd(min));
            double step = rnd((max - min) / 2.0);
            cs_color_low.Add(lowCol);
            cs_color_high.Add(midCol);
            cs_low.Add(rnd(min));
            cs_high.Add(rnd(min + (1.0 * step)));
            cs_color_low.Add(midCol);
            cs_color_high.Add(higCol);
            cs_low.Add(rnd(min + (1.0 * step)));
            cs_high.Add(rnd(max));
            cs_color_low.Add(higCol);
            cs_color_high.Add(higCol);
            cs_low.Add(rnd(max));
            cs_high.Add(rnd(max2));
            bool found = false;
            for (int i = 0; i < arX.Count; i++)
            {
                found = false;
                for (int j = 0; j < cs_low.Count; j++)
                {
                    if (!found && (double)arX[i] >= (double)cs_low[j] && (double)arX[i] < (double)cs_high[j])
                    {
                        arC.Add(graduateColor((double)arX[i], (double)cs_low[j], (double)cs_high[j],
                                                               (Color)cs_color_low[j], (Color)cs_color_high[j]));
                        found = true;
                    }
                }
                if (!found) arC.Add(Color.Black);
            }
            return arC;
        }
        // gets interpolated color from color break
        private Color graduateColor(double v, double vlow, double vhigh, Color clow, Color chigh)
        {
            byte al, rl, gl, bl;
            byte au, ru, gu, bu;
            byte a , r, g, b;
            Color cg;
            double ratio;
            if (v < vlow || v >= vhigh) return Color.White;
            al = clow.A;
            rl = clow.R;
            gl = clow.G;
            bl = clow.B;
            au = chigh.A;
            ru = chigh.R;
            gu = chigh.G;
            bu = chigh.B;
            ratio = (v - vlow) / (vhigh - vlow);
            a = (byte)(al + (ratio * (au - al)));
            r = (byte)(rl + (ratio * (ru - rl)));
            g = (byte)(gl + (ratio * (gu - gl)));
            b = (byte)(bl + (ratio * (bu - bl)));
            cg = Color.FromArgb(r, g, b);
            return cg;
        }

            
        
       




        private double rnd(double v)
        {
            double v2 = 0.0;
            if (v > 100.0 || v < -100.0)
            {
                v2 = Math.Round(v, 0);
            }
            else if (v > 10.0 || v < -10.0)
            {
                v2 = Math.Round(v, 1);
            }
            else if (v > 1.0 || v < -1.0)
            {
                v2 = Math.Round(v, 2);
            }
            else
            {
                v2 = Math.Round(v, 3);
            }
            return v2;
        }
    }
}
